import os
import zmail
from datetime import datetime
from jinja2 import Environment, FileSystemLoader
from config.conf import cm
from pathlib import Path
import importlib.util


def generate_test_report(test_results):
    """生成HTML测试报告"""
    # 准备报告数据（模拟数据，实际应从测试框架获取）
    report_data = {
        "title": "自动化测试报告",
        "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "total_tests": len(test_results),
        "passed": sum(1 for r in test_results if r['status'] == 'pass'),
        "failed": sum(1 for r in test_results if r['status'] == 'fail'),
        "test_cases": test_results
    }

    # template_dir = os.path.join(os.path.dirname(__file__), "templates")
    # env = Environment(loader=FileSystemLoader(template_dir))
    env = Environment(loader=FileSystemLoader('D:/pythonProject/pom/templates'))
    # 渲染HTML
    template = env.get_template('report_template.html')
    html_content = template.render(**report_data)

    # 保存报告
    with open(cm.REPORT_FILE, 'w', encoding='utf-8') as f:
        f.write(html_content)

    return cm.REPORT_FILE


def pytest_terminal_summary(terminalreporter, exitstatus, config):
    """在测试结束后生成报告并发送邮件"""
    test_results = []
    for test in terminalreporter.stats.get("passed", []):
        test_results.append({
            "name": test.nodeid,
            "status": "pass",
            "duration": f"{test.duration:.2f}s",
            "error": ""
        })
    for test in terminalreporter.stats.get("failed", []):
        test_results.append({
            "name": test.nodeid,
            "status": "fail",
            "duration": f"{test.duration:.2f}s",
            "error": str(test.longrepr)
        })

    # 保存测试结果到全局变量或文件中，以便 send_report 使用
    global TEST_RESULTS
    TEST_RESULTS = test_results
    generate_test_report(test_results)


def send_report():
    """发送测试报告邮件"""
    try:
        # 读取报告内容
        with open(cm.REPORT_FILE, encoding='utf-8') as f:
            content_html = f.read()

        # 配置邮件
        mail = {
            'from': cm.EMAIL_INFO['username'],
            'subject': f'测试报告 {datetime.now().strftime("%Y-%m-%d")}',
            'content_html': content_html,
            'attachments': [cm.REPORT_FILE]
        }

        # 发送邮件
        server = zmail.server(
            cm.EMAIL_INFO['username'],
            cm.EMAIL_INFO['password'],
            smtp_host=cm.EMAIL_INFO['smtp_host'],
            smtp_port=cm.EMAIL_INFO['smtp_port'],
            smtp_ssl=True
        )
        server.send_mail(cm.ADDRESSEE, mail)
        print(f"邮件发送成功！收件人: {cm.ADDRESSEE}")

    except Exception as e:
        print(f"邮件发送失败: {str(e)}")


def get_test_cases_from_directory(directory='testCase'):
    """从testCase目录获取所有测试用例"""
    test_cases = []

    # 遍历testCase目录
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.startswith('test_') and file.endswith('.py'):
                # 获取模块的完整路径
                module_path = os.path.join(root, file)
                module_name = os.path.splitext(file)[0]

                # 动态导入模块
                spec = importlib.util.spec_from_file_location(module_name, module_path)
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                # 获取模块中的所有测试函数
                for name in dir(module):
                    if name.startswith('test_'):
                        test_cases.append({
                            "name": f"{module_name}.{name}",
                            "status": "unknown",  # 实际运行时会被pytest_terminal_summary更新
                            "duration": "0s",
                            "error": ""
                        })

    return test_cases


def mock_test_results():
    """模拟测试数据（实际项目应替换为真实测试结果）"""
    # return [
    #     {"name": "test_login", "status": "pass", "duration": "1.2s", "error": ""},
    #     {"name": "test_search", "status": "fail", "duration": "0.8s", "error": "元素未找到"}
    # ]
    # 替换为实际测试结果 目录是testCase里的内容
    return get_test_cases_from_directory()


# 测试代码
if __name__ == "__main__":
    # 1. 模拟运行测试并获取结果
    test_results = mock_test_results()

    # 2. 生成报告
    report_path = generate_test_report(test_results)
    print(f"报告已生成: {report_path}")

    # 3. 发送邮件
    send_report()

